package com.oracle.scjp.threads;

public class MultipleLocks {

	public static void main(String[] args) {
		Sample test = new Sample();
		new Locker(test, "first").start();
		new Locker(test, "second").start();
		new Locker(test, "three").start();
		new Locker(test, "four").start();
	}
	
}

class Locker extends Thread {
	
	private Sample test;
	
	public Locker(Sample test, String name) {
		super(name);
		this.test = test;		
	}
	
	@Override
	public void run() {
		System.out.println(getName() + ".run() is started...");
		synchronized (test) {
			System.out.println(getName() + " lock test object. #1");
			// this sleep is for giving execution to other threads
			// they will printout the first statement
			// then they will be locked!
			sleepForWhile(1000); 
			synchronized (test) {
				System.out.println(getName() + " lock test object. #2");
				synchronized (test) {
					System.out.println(getName() + " lock test object. #3");
					test.notifyAll(); // it is  optional
				}	
			}	
		}
	}
	
	private void sleepForWhile(long ms) {
		try {
			Thread.sleep(ms);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class Sample { }